package com.cc.mall.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.alipay.api.AlipayApiException;
import com.cc.common.utils.R;
import com.cc.mall.config.AlipayTemplate;
import com.cc.mall.entity.*;
import com.cc.mall.feign.UserFeign;
import com.cc.mall.service.*;
import com.cc.mall.vo.*;
import com.cc.user.entity.ScheduleEntity;
import com.cc.user.entity.UserEntity;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.cc.mall.dao.ProductDetailDao;
import org.springframework.util.StringUtils;


@Service("productDetailService")
public class ProductDetailServiceImpl extends ServiceImpl<ProductDetailDao, ProductDetailEntity> implements ProductDetailService {

    @Autowired
    private ProductDetailService productDetailService;

    @Autowired
    private AlipayTemplate alipayTemplate;

    @Autowired
    private UserFeign userFeign;

    @Autowired
    private OnlineOrderService orderService;

    @Autowired
    private OnlineOrderProductService orderProductService;

    @Autowired
    private OfflineOrderProductService offlineOrderProductService;

    @Autowired
    private OfflineOrderService offlineOrderService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ProductService productService;

    @Autowired
    private ThreadPoolExecutor executor;

    @Override
    public void addToCart(Long skuId, Integer num, Long uid) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps(uid);
        Object o = cartOps.get(skuId.toString());
        //CartItem cartItem = (CartItem) ops.get(skuId.toString());
        if(o == null){
            CartItem cartItem = new CartItem();
            ProductDetailEntity productDetailEntity = baseMapper.selectById(skuId);
            if(productDetailEntity != null) {
                BeanUtils.copyProperties(productDetailEntity, cartItem);

                ProductEntity productEntity = productService.getById(productDetailEntity.getPid());
                if(productEntity != null){
                    cartItem.setBigTitle(productEntity.getBigTitle());
                    cartItem.setSmallTitle(productEntity.getSmallTitle());
                    cartItem.setDefaultPicture(productEntity.getDefaultPicture());
                    // todo
                }

                cartItem.setCount(num);
                cartItem.setTotalPrice(cartItem.getTotalPrice());
                cartOps.put(skuId.toString(), cartItem);
            }
        }else {
            CartItem cartItem = (CartItem) o;
            int i = cartItem.getCount() + num;
            if(i <= 0){
                cartOps.delete(skuId.toString());
            }else {
                cartItem.setCount(i);
                cartOps.put(skuId.toString(),cartItem);
            }
        }
    }

    @Override
    public Cart getCart(Long uid) {
        Cart cart = new Cart();
        BoundHashOperations<String,Object,Object>  ops = getCartOps(uid);
        List<Object> values = ops.values();
        List<CartItem> collect = values.stream().map(m -> {
            return (CartItem) m;
        }).collect(Collectors.toList());
        cart.setCartItemList(collect);

        return cart;
    }

    @Override
    public void deleteCartItem(Long[] skuIds, Long uid) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps(uid);
        for (Long skuId : skuIds) {
            cartOps.delete(skuId.toString());
        }
    }

    @Override
    public void updateStatus(Long[] skuIds, Long uid) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps(uid);
        for (Long skuId : skuIds) {
            CartItem cartItem = (CartItem)cartOps.get(skuId.toString());
            if(cartItem !=null){
                cartItem.setCheck(!cartItem.getCheck());
            }
            cartOps.put(skuId.toString(),cartItem);
        }

    }

    @Override
    public Long createOrder(Long[] skuIds, Long uid, Long cid,Long rid) throws AlipayApiException, ExecutionException, InterruptedException {
        BigDecimal amountsPayable = new BigDecimal("0"); // 用于计算应付款
        BoundHashOperations<String, Object, Object> cartOps = getCartOps(uid);
        if(cid !=null){
            // todo 为客户下单
            // 封装好订单详情的集合，然后批量插入 (没有包括ooid)
            R kehuInfo = userFeign.getKehuInfo(cid);
            UserEntity userEntity = kehuInfo.getData("user", new TypeReference<UserEntity>() {
            });
            List<OfflineOrderProductEntity> offlineOrderProductEntities = new ArrayList<>();
                for (Long skuId : skuIds) {
                    CartItem cartItem = (CartItem) cartOps.get(skuId.toString());
                    OfflineOrderProductEntity offlineOrderProductEntity = new OfflineOrderProductEntity();
                    if(cartItem != null){
                        offlineOrderProductEntity.setPdid(skuId);
                        offlineOrderProductEntity.setProductName(cartItem.getBigTitle()+" "+cartItem.getSmallTitle());
                        offlineOrderProductEntity.setProductPicture(cartItem.getDefaultPicture());
                        offlineOrderProductEntity.setProductNumber(cartItem.getCount().longValue()); // 商品详情数量
                        offlineOrderProductEntity.setPaymentPrice(cartItem.getProductPrice()); // 商品详情单价
                        offlineOrderProductEntity.setProductPrice(cartItem.getTotalPrice());
                        offlineOrderProductEntity.setProductSize(cartItem.getProductSize());
                        amountsPayable = amountsPayable.add(cartItem.getTotalPrice()); // 求应付款和
                    }
                    offlineOrderProductEntities.add(offlineOrderProductEntity);
                }
            OfflineOrderEntity offlineOrderEntity = new OfflineOrderEntity();
            // 封装线下订单entity
            if(userEntity != null){
                // 小心id
                offlineOrderEntity.setReceiveAddress(userEntity.getShopAddress());// 地址信息
                offlineOrderEntity.setReceiverMobile(userEntity.getMobile());
                offlineOrderEntity.setReceiverName(userEntity.getContactName()); // todo
            }

            offlineOrderEntity.setEid(uid);
            offlineOrderEntity.setCid(cid);
            offlineOrderEntity.setCreatetime(new Date());
            offlineOrderEntity.setAmountsPaid(new BigDecimal("0")); // 已付款
            offlineOrderEntity.setAmountsPayable(amountsPayable); // 应付款
            offlineOrderService.save(offlineOrderEntity);

            CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
                // 为线下订单详情再次封装ooid
                for (OfflineOrderProductEntity offlineOrderProductEntity : offlineOrderProductEntities) {
                    offlineOrderProductEntity.setOoid(offlineOrderEntity.getId());
                }
                // 对订单详情进行批量插入
                offlineOrderProductService.saveBatch(offlineOrderProductEntities);
            }, executor);
            CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> {
                UserEntity user = kehuInfo.getData("user", new TypeReference<UserEntity>() {
                });
                String nickname = user.getNickname();
                String shopName = user.getShopName();
                String content = "您已成功为客户";
                ScheduleEntity scheduleEntity = new ScheduleEntity();
                scheduleEntity.setUid(uid);
                scheduleEntity.setCreatetime(new Date());
                scheduleEntity.setScheduleStatus(0);
                if(!StringUtils.isEmpty(nickname)){
                    content = content+":"+nickname;
                }
                if(!StringUtils.isEmpty(shopName)){
                    content = content+"("+shopName+")";
                }
                content = content + "下单";
                scheduleEntity.setContent(content);
                userFeign.save(scheduleEntity);
            }, executor);
            CompletableFuture<Void> future3 = CompletableFuture.runAsync(() -> {
                // 扣库存
                productDetailService.plgxKucun(offlineOrderProductEntities);
            }, executor);
            CompletableFuture.allOf(future1,future2,future3).get();
            return offlineOrderEntity.getId();
        }else {
            // 根据地址rid去查出收货地址
            R addressInfo = userFeign.info(rid);
            AddressVo receiveAddress = addressInfo.getData("receiveAddress", new TypeReference<AddressVo>() {
            });
            // 封装好订单详情的集合，然后批量插入 (没有包括ooid)
            List<OnlineOrderProductEntity> onlineOrderProductEntities = new ArrayList<>();
            for (Long skuId : skuIds) {
                CartItem cartItem = (CartItem) cartOps.get(skuId.toString());
                OnlineOrderProductEntity orderProductEntity = new OnlineOrderProductEntity();
                if(cartItem != null){
                    orderProductEntity.setProductPicture(cartItem.getDefaultPicture());
                    orderProductEntity.setProductPrice(cartItem.getTotalPrice());
                    orderProductEntity.setProductName(cartItem.getBigTitle()+" "+cartItem.getSmallTitle());
                    orderProductEntity.setProductSize(cartItem.getProductSize());
                    orderProductEntity.setProductNumber(cartItem.getCount().longValue()); // 商品详情数量
                    orderProductEntity.setPaymentPrice(cartItem.getProductPrice()); // 商品详情单价
                    amountsPayable = amountsPayable.add(cartItem.getTotalPrice()); // 求应付款和
                }
                onlineOrderProductEntities.add(orderProductEntity);
            }
            // 封装订单信息
            OnlineOrderEntity orderEntity = new OnlineOrderEntity();
            if(receiveAddress != null){
                BeanUtils.copyProperties(receiveAddress,orderEntity,"id","uid");// 地址信息
            }

            orderEntity.setUid(uid);
            orderEntity.setAmountsPayable(amountsPayable);
            orderEntity.setAmountsPaid(new BigDecimal("0"));
            orderEntity.setCreatetime(new Date());
            orderService.save(orderEntity);
            Long orderId = orderEntity.getId();
            CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
                // 再次封装订单详情的ooid
                for (OnlineOrderProductEntity onlineOrderProductEntity : onlineOrderProductEntities) {
                    onlineOrderProductEntity.setOoid(orderId);
                }
                // 批量插入线上订单详情表
                orderProductService.saveBatch(onlineOrderProductEntities);
            }, executor);
            CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> {
                // 将带付款的线上订单放入redis，方便扣库存
                List<CartItem> cartItemList = new ArrayList<>();
                for (Long skuId : skuIds) {
                    CartItem cartItem = (CartItem) cartOps.get(skuId.toString());
                    if(cartItem != null){
                        cartItemList.add(cartItem);
                    }
                }
                redisTemplate.opsForValue().set(orderId.toString(),cartItemList);
            }, executor);
            CompletableFuture<Void> future3 = CompletableFuture.runAsync(() -> {
                ScheduleEntity scheduleEntity = new ScheduleEntity();
                scheduleEntity.setUid(uid);
                scheduleEntity.setCreatetime(new Date());
                scheduleEntity.setScheduleStatus(0);
                scheduleEntity.setContent("您的订单【"+orderId+"】【待付款】");
                userFeign.save(scheduleEntity);
            }, executor);
            CompletableFuture.allOf(future1,future2,future3).get();
            return orderId;
        }
    }

    @Override
    public OrderVo toTrade(Long[] skuIds, Long uid) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps(uid);
        OrderVo orderVo = new OrderVo();
        ArrayList<OrderItem> orderItems = new ArrayList<>();
        for (Long skuId : skuIds) {
            CartItem cartItem = (CartItem) cartOps.get(skuId.toString());
            OrderItem orderItem = new OrderItem();
            if(cartItem !=null){
                BeanUtils.copyProperties(cartItem, orderItem);
                orderItem.setProductName(cartItem.getBigTitle()+" "+cartItem.getSmallTitle());
            }

            orderItems.add(orderItem);
        }
        orderVo.setUid(uid);
        orderVo.setOrderItemList(orderItems);
        orderVo.setCreatetime(new Date());
        orderVo.setStatus(0);
        return orderVo;
    }

    /*@Override
    public List<OrderVo> getOrderByUid(Long uid,Integer type) {
        // 根据uid，获取绑定对应的redis购物车
        BoundHashOperations<String, Object, Object> cartOps = getCartOps(uid);
        List<OrderVo> orderVos = new ArrayList<>();
        if(type == 1){
            // 员工
            // 根据员工uid，得到员工下的线上订单
            getOnlineOrder(uid, cartOps, orderVos);
            // 根据员工uid，得到员工的线下订单
            getOfflineOrderByUid(uid, cartOps, orderVos);
        }else {
            // 客户
            // 根据客户uid，得到客户下的线上订单
            getOnlineOrder(uid,cartOps,orderVos);
            // todo 员工为客户下单的订单项 根据客户的uid得到对应业务员的eid
            Long eid = userFeign.getEidByCid(uid);
            // 根据客户uid，得到客户的线下订单 todo 客户是否需要获取业务员为他下的线下订单?

            getOfflineOrderByCid(uid,getCartOps(eid),orderVos);
        }
        return orderVos;
    }*/

    @Override
    public List<OrderVo> getOrderByUid(Long uid,Integer type,Integer status) throws ExecutionException, InterruptedException {
        List<OrderVo> orderVos = new ArrayList<>();
        if(type == 1){
            // 员工
            CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
                // 根据员工uid，得到员工下的线上订单
                getOnlineOrder2(uid, orderVos, status);
            }, executor);

            CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> {
                // 根据员工uid，得到员工的线下订单
                getOfflineOrder2(uid, orderVos, status);
            }, executor);
            CompletableFuture.allOf(future1,future2).get();
        }else {
            // 客户
            CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
                // 根据客户uid，得到客户下的线上订单
                getOnlineOrder2(uid,orderVos,status);
            }, executor);

            CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> {
                // 根据客户uid，得到客户的线下订单 todo 客户是否需要获取业务员为他下的线下订单?
                getOfflineOrderByCid2(uid,orderVos,status);
            }, executor);
            CompletableFuture.allOf(future1,future2).get();
        }
        return orderVos;
    }

    private void getOfflineOrderByCid2(Long uid, List<OrderVo> orderVos, Integer status) {
        List<OrderVo> offlineOrderByCid2 = baseMapper.getOfflineOrderByCid2(uid,status);
        orderVos.addAll(offlineOrderByCid2);
    }

    private void getOfflineOrder2(Long uid, List<OrderVo> orderVos, Integer status) {
        List<OrderVo> offlineoderVo2 = baseMapper.getOfflineOrder2(uid,status);
        orderVos.addAll(offlineoderVo2);
    }

    private void getOnlineOrder2(Long uid, List<OrderVo> orderVos, Integer status) {
        List<OrderVo> onlineOrder2 = baseMapper.getOnlineOrder2(uid,status);
        orderVos.addAll(onlineOrder2);
    }

    @Override
    public String payOrder(Long orderId) throws AlipayApiException {
        /*// 删除原订单记录，创建新订单
        OnlineOrderEntity byId = orderService.getById(orderId);
        orderProductService.remove(new QueryWrapper<OnlineOrderProductEntity>().eq("pdid",skuId).eq("ooid",orderId));
        OnlineOrderEntity onlineOrderEntity = new OnlineOrderEntity();
        onlineOrderEntity.setRaid(byId.getRaid());
        onlineOrderEntity.setUid(byId.getUid());
        onlineOrderEntity.setCreatetime(byId.getCreatetime());
        orderService.save(onlineOrderEntity);
        OnlineOrderProductEntity onlineOrderProductEntity = new OnlineOrderProductEntity();
        onlineOrderProductEntity.setOoid(onlineOrderEntity.getId());
        onlineOrderProductEntity.setPdid(skuId);
        orderProductService.save(onlineOrderProductEntity);*/
        OnlineOrderEntity onlineOrderEntity = orderService.getById(orderId);
        PayVo payVo = new PayVo();
        payVo.setBody("商品描述");
        payVo.setSubject("宣酒"); // todo 待定
        payVo.setOut_trade_no(onlineOrderEntity.getId().toString());
        payVo.setTotal_amount(onlineOrderEntity.getAmountsPayable().toString());
        String pay = alipayTemplate.pay(payVo);
        ScheduleEntity scheduleEntity = new ScheduleEntity();
        scheduleEntity.setUid(onlineOrderEntity.getUid());
        scheduleEntity.setCreatetime(new Date());
        scheduleEntity.setScheduleStatus(0);
        scheduleEntity.setContent("您的订单【"+orderId+"】【待付款】");
        userFeign.save(scheduleEntity);
        return pay;
    }

    @Override
    public void removeOrder(Long orderId,Integer orderType) {
        if(orderType == 1){
            // 线上订单
            // 1.先删除对应的订单详情
            orderProductService.remove(new QueryWrapper<OnlineOrderProductEntity>().eq("ooid",orderId));
            // 2.再删除订单
            orderService.removeById(orderId);
        }else {
            // 线下订单
            // 1.先删除对应的订单详情
            offlineOrderProductService.remove(new QueryWrapper<OfflineOrderProductEntity>().eq("ooid",orderId));
            // 2.再删除订单
            offlineOrderService.removeById(orderId);
        }
    }

    @Override
    public void confirmRecieve(Long orderId, Integer orderType) {
        if(orderType == 1){
            // 线上订单
            OnlineOrderEntity onlineOrderEntity = new OnlineOrderEntity();
            onlineOrderEntity.setId(orderId);
            onlineOrderEntity.setOnlineOrderStatus(3); // 修改为已收货
            orderService.updateById(onlineOrderEntity);
        }else {
            // 线下订单
            OfflineOrderEntity offlineOrderEntity = new OfflineOrderEntity();
            offlineOrderEntity.setId(orderId);
            offlineOrderEntity.setOfflineOrderStatus(3); // 修改为已收货
            offlineOrderService.updateById(offlineOrderEntity);
        }
    }

    @Override
    public List<Long> checkProductOver(Long[] skuIds) {
        return baseMapper.checkProductOver(skuIds);
    }

    @Override
    public List<Kucun> getOnlineKucun() {
        return baseMapper.getOnlineKucun();
    }

    @Override
    public List<Kucun> getOfflineKucun() {
        return baseMapper.getOfflineKucun();
    }

    // 商品详情页中的立即结算
    @Override
    public void addToCart2(Long skuId, Integer num, Long uid) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps(uid);
        Object o = cartOps.get(skuId.toString());
        //CartItem cartItem = (CartItem) ops.get(skuId.toString());
        if(o == null){
            CartItem cartItem = new CartItem();
            ProductDetailEntity productDetailEntity = baseMapper.selectById(skuId);
            if(productDetailEntity != null) {
                BeanUtils.copyProperties(productDetailEntity, cartItem);

                ProductEntity productEntity = productService.getById(productDetailEntity.getPid());
                if(productEntity != null){
                    cartItem.setBigTitle(productEntity.getBigTitle());
                    cartItem.setSmallTitle(productEntity.getSmallTitle());
                    cartItem.setDefaultPicture(productEntity.getDefaultPicture());
                }

                cartItem.setCount(num);
                cartItem.setTotalPrice(cartItem.getTotalPrice());
                cartOps.put(skuId.toString(), cartItem);
            }
        }else {
            CartItem cartItem = (CartItem) o;
            cartItem.setCount(num);
            cartOps.put(skuId.toString(),cartItem);
        }
    }

    @Override
    public List<ProductDetailEntity> koukucun(Long orderId) {
        return baseMapper.koukucun(orderId);
    }

    @Override
    public void plgxKucun(List<OfflineOrderProductEntity> offlineOrderProductEntities) {
        baseMapper.plgxKucun(offlineOrderProductEntities);
    }

    @Override
    public void koukucun2(List<CartItem> cartItemList) {
        baseMapper.koukuncun2(cartItemList);
    }

    private BoundHashOperations<String,Object,Object> getCartOps(Long uid){
        return redisTemplate.boundHashOps(uid.toString());
    }
}